//Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;

namespace Eas.WebCrawler.PlugIns.RequestComparers
{
    /// <summary>A base class for <see cref="BaseComparer"/>s that uses the concept of desirability to help define priority.</summary>
    /// <remarks>There are sometimes where priority is defined like this 'do all the requests that stay on the same host before processing requests that move to a different host' or
    /// 'do all requests that are images before everything else'.  To make this simple, this class defines the concept of 'desirability'.  Desirability is a boolean value, something is either desirable (i.e. the link stays on the same host, or is an image or something) or it is not desirable.
    /// Derived classes implement the <see cref="IsPreferred"/> method to determine if a link is desirable, and this class will then rank all desirable links as being higher priority then non-desirable ones.
    /// In the case that the links being proritized are either both desirable or both undesirable, then the comparison is delegated to another comparer.</remarks>
    public abstract class BaseRequestDesirabilityComparer : DecoratingComparer
    {
        /// <summary>Constructs a <see cref="BaseRequestDesirabilityComparer"/> from an inner <see cref="BaseComparer"/>.</summary>
        /// <param name="innerComparer">The inner <see cref="BaseComparer"/> to which dervied classes can delegate.</param>
        protected BaseRequestDesirabilityComparer(BaseComparer innerComparer) : base(innerComparer) { }

        /// <summary>Compares two <see cref="Uri"/>s to see which is higher priority.</summary>
        /// <param name="leftRequest">The left <see cref="Eas.WebCrawler.Interfaces.Request"/> to compare.</param>
        /// <param name="rightRequest">The right <see cref="Eas.WebCrawler.Interfaces.Request"/> to compare.</param>
        /// <returns>A <see cref="CompareResult"/> declaring if the left or right <see cref="Eas.WebCrawler.Interfaces.Request"/> is higher priority.</returns>
        public override CompareResult CompareUris(Eas.WebCrawler.Interfaces.Request leftRequest, Eas.WebCrawler.Interfaces.Request rightRequest)
        {
            bool leftPrefered = IsPreferred(leftRequest);
            bool rightPrefered = IsPreferred(rightRequest);

            if (leftPrefered == rightPrefered)
                return base.CompareUris(leftRequest, rightRequest);
            else if (leftPrefered)
                return CompareResult.LeftIsHigherPriority;
            else
                return CompareResult.RightIsHigherPriority;
        }


        /// <summary>Derived classes must implement this function to determine whether or not a link is desirable.  In effect, this function defines desirability for the class.</summary>
        /// <param name="request">The request whose desirability must be determined.</param>
        /// <returns><code>true</code> if the request is desirable, otherwise <code>false</code>.</returns>
        public abstract bool IsPreferred(Eas.WebCrawler.Interfaces.Request request);

    }
}
